import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import Dom from '../utils/Dom';
import Events from '../utils/Events';
import Dropdown from '../Dropdown';

import './ContextMenu.less';

class ContextMenu extends React.Component {
    displayName = 'ContextMenu';

    static defaultProps = {
        target: 'body'
    };

    static propTypes = {
        onSelect: PropTypes.func,
        overlay: PropTypes.element
    };

    onClick = (event) => {
        if (this.clickTimer) {
            window.clearTimeout(this.clickTimer);
            this.clickTimer = null;
        }
        this.clickTimer = window.setTimeout(() => {
            this.hideMenu();
        }, 200);
    }

    componentWillUnmount () {
        Events.off(document, 'contextmenu', this.onContextMenu);
        Events.off(document, 'mousewheel', this.onScroll);
        Events.off(document, 'click', this.onClick);
    }

    componentDidMount () {
        Events.on(document, 'contextmenu', this.onContextMenu);
        Events.on(document, 'mousewheel', this.onScroll);
        Events.on(document, 'click', this.onClick);

        const wrap = document.createElement('div');
        wrap.className = 'cm-contextmenu';
        document.body.appendChild(wrap);
        this.layer = wrap;

        this.renderMenu();
    }

    saveRef = (f) => {
        this.overlay = f;
    }

    onScroll = (event) => {
        if (this.scrollTimer) {
            window.clearTimeout(this.scrollTimer);
            this.scrollTimer = null;
        }
        this.scrollTimer = window.setTimeout(() => {
            this.hideMenu();
        }, 300);
    }

    onContextMenu = (event) => {
        const target = Dom.closest(event.target, this.props.target);
        if (target) {
            event.preventDefault();
            this.showMenu(event);
        } else {
            const menu = Dom.closest(event.target, '.cm-contextmenu');
            // on Menu
            if (menu) {
                return false;
            } else {
                this.hideMenu();
            }
        }
    }

    getTrigger () {
        return this.target;
    }

    showMenu (event) {
        const x = event.clientX;
        const y = event.clientY;
        if (this.layer) {
            this.layer.classList.add('cm-contextmenu-visible');
            this.layer.style.position = 'fixed';
            this.layer.style.left = `${x}px`;
            this.layer.style.top = `${y}px`;
            this.target = event.target;
        }
        this.dropdown.showOrHide(true);
    }

    hideMenu () {
        if (this.layer) {
            this.layer.classList.remove('cm-contextmenu-visible');
        }
        this.dropdown.showOrHide(false);
    }

    /**
     * 渲染菜单
     */
    renderMenu () {
        ReactDOM.render(<Dropdown align='rightBottom' trigger='click' ref={f => this.dropdown = f} 
            data={this.props.data} onSelect={this.props.onSelect}/>, this.layer);
    }

    render () {
        return null;
    }
}
export default ContextMenu;
